package org.tigr.htc.server;

/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

import java.io.File;
import java.util.Date;

import org.apache.log4j.Logger;
import org.tigr.antware.shared.command.events.CommandRuntimeStatusLI;
import org.tigr.antware.shared.command.events.CommandStatusLI;
import org.tigr.antware.shared.command.events.FailureEvent;
import org.tigr.antware.shared.command.events.FinishEvent;
import org.tigr.antware.shared.command.events.InterruptEvent;
import org.tigr.antware.shared.command.events.ResumeEvent;
import org.tigr.antware.shared.command.events.StartEvent;
import org.tigr.antware.shared.command.events.SubmitEvent;
import org.tigr.antware.shared.command.events.SuspendEvent;
import org.tigr.htc.cmd.CommandSet;
import org.tigr.htc.cmd.ICommand;

/**
 * The <b>CompositeRunner</b> class that runs a MacroCommand
 *
 */

public class CompositeRunner implements IRunner, CommandStatusLI, CommandRuntimeStatusLI {
    static Logger log = Logger.getLogger(CompositeRunner.class);
    protected CommandSet cmdSet;
    protected File cwd;
    protected int index = 0;
    protected Scheduler sched = Scheduler.getInstance();

    public CompositeRunner(CommandSet cmdSet, File cwd) {
        this.cmdSet = cmdSet;
        this.cwd = cwd;
    }


    public ICommand getICommand() {
    	return cmdSet;
    }

    public void run() {
    	log.debug("In run().");

    	try {
    		ICommand cmd = cmdSet.getCommand(index++);
    		cmd.addRuntimeStatusListener(this);
    		cmd.addStatusListener(this);
    		sched.enqueue(cmd);
    	} catch (Exception e) {
    		log.warn("Command set error " + e.getMessage(), e);
    		// failure event

    	}
    }

    public boolean isRunnerComplete() {
    	return true;
    }

    public boolean stop() throws Exception {
        return false;
    }

    public boolean hold() throws Exception {
        return false;
    }

    public boolean release() throws Exception {
        return false;
    }


    // CommandStatusLI methods
    public void commandStarted(StartEvent event) {
    	log.debug("Command #" + event.getMessage() + " started");
    }

    public void commandRestarted(StartEvent event) {
    	log.debug("Command #" + event.getMessage() + " restarted");
    }

    public void commandInterrupted(InterruptEvent event) {
    	log.debug("CommandSet #" + event.getMessage() + " interrupted");
    	cmdSet.fireInterruptEvent(event);
    	log.debug("command set has been interrupted");
    }

    public void commandFailed(FailureEvent event) {
    	log.debug("Got failed event for " + event);

		cmdSet.fireFailureEvent(event);
		log.debug("CommandSet has failed");
    }

    // CommandRuntimeStatusLI methods
    public void commandSubmitted(SubmitEvent event) {
    	log.debug("Got submitted event for " + event.getMessage());
    }

    public void commandResumed(ResumeEvent event) {
    	log.debug("Got resume event for " + event.getMessage());
    }

    public void commandSuspended(SuspendEvent event) {
    	log.debug("Got suspend event for " + event.getMessage());
    }


    public void commandFinished(FinishEvent event) {
    	log.debug("Got finish event for " + event);
    	if(cmdSet.getCommandsCount() > index) {
    		ICommand cmd = cmdSet.getCommand(index++);
    		cmd.addStatusListener(this);
    		cmd.addRuntimeStatusListener(this);

    		log.debug("Composite about to enqueue cmd " + cmd.getID());
    		try {
    			sched.enqueue(cmd);
    		} catch(Exception e) {
    			log.error("Implement failure code");
    		}
    	} else { 
    		FinishEvent fe = 
    			new FinishEvent((Object)cmdSet, cmdSet.getID(), 
    					new Date(), "CommandSet Finished", 0);
    		cmdSet.fireFinishEvent(fe);
    		log.debug("CommandSet is finished");
    	}
    }

}
